<template>
  <view class="chat-item" :class="{'is-self': message['is_self']}">
    <image :src="user.face" class="chat-face" />
    <view class="chat-content" :class="message.type" @tap="handleClickMessage">
      <!-- 文字[emoji]消息 -->
      <view v-if="message.type === 'TEXT'">
        <rich-text :nodes="textMessage" class="rich-text"></rich-text>
      </view>
      <!-- 商品消息 -->
      <view v-else-if="message.type === 'GOODS'" class="goods-message">
        <image :src="message['goods_image']" class="goods-image" />
        <view class="goods-info">
          <text class="goods-name">{{ message['goods_name'] }}</text>
          <text class="goods-price">￥{{ message['goods_price'] }}</text>
        </view>
      </view>
      <!-- 订单消息 -->
      <view v-else-if="message.type === 'ORDER'" class="order-message">
        <view class="order-info">
          <text>订单号: {{ message['order_sn'] }}</text>
          <text style="width: 30%;">{{ formatDate(message['create_time'], 'MM-dd hh:mm') }}</text>
        </view>
        <view class="order-goods" v-for="goods in message.goods_list" :key="goods.name">
          <image :src="goods['goods_image']" class="goods-image" />
          <view class="goods-info">
            <text class="goods-name">{{ goods['goods_name'] }}</text>
          </view>
        </view>
          <view class="order-price-status">
              <text class="order-price">订单金额：￥{{ message['order_price'] }}</text>
              <text class="order-status">{{ message['order_status'] }}</text>
          </view>
      </view>
      <!-- 图片消息 -->
      <view v-else-if="message.type === 'IMAGES'" class="image-message">
        <img :src="message.url" class="image" alt="" />
      </view>
      <!-- 视频消息 -->
      <view v-else-if="message.type === 'VIDEO'" class="video-message">
        <!-- 非H5端不直接显示video组件，使用canvas绘制封面代替，避免层级问题 -->
        <video :src="message.url" :id="`video-${message['msg_id']}`" class="video" @fullscreenchange="handlePauseVideo" />
        <!-- #ifndef H5 -->
        <canvas :canvas-id="`canvas-${message['msg_id']}`" type="2d" style="width:300rpx;height:300rpx;"></canvas>
        <!-- #endif -->
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'chat-item',
  props: {
    message: {
      type: Object,
      required: true
    },
    sender: {
      type: Object,
      required: false
    },
    receiver: {
      type: [Object, String],
      required: false
    },
    getEmojiPath: Function,
    formatDate: Function
  },
  data() {
    return {
      videoCtx: ''
    }
  },
  computed: {
    user() {
      return this.message['is_self'] ? this.sender : this.receiver
    },
    textMessage() {
      const { text } = this.message
      if (!text) return
      return this.message.text.replace(/alt="(e\d+)"/g, this.getEmojiSrc)
    }
  },
  mounted() {
    const { type, url } = this.message
    if (type !== 'VIDEO') return
    // #ifndef H5
    const ctx = uni['createCanvasContext'](`canvas-${this.message['msg_id']}`, this)
    this.drawRoundedRect(ctx, 0, 0, uni.upx2px(300), uni.upx2px(300), uni.upx2px(20))
    ctx.clip()
    ctx.drawImage(url, 0, 0, uni.upx2px(300), uni.upx2px(300))
    ctx.draw()
    this.videoCtx = uni['createVideoContext'](`video-${this.message['msg_id']}`, this)
    // #endif
  },
  methods: {
    /**
     * 获取emoji完整src
     * @param _
     * @param emojiId
     * @returns {string}
     */
    getEmojiSrc(_, emojiId) {
      return `alt="${emojiId}" src="${this.getEmojiPath(emojiId)}"`
    },
    /**
     * 点击了消息
     */
    handleClickMessage() {
      // #ifndef H5
      if (this.message.type === 'VIDEO') {
        this.videoCtx['requestFullScreen']({
          direction: 0
        })
      }
      // #endif
      this.$emit('handle-click', this.message)
    },
    /**
     * 暂停视频
     */
    handlePauseVideo() {
      this.videoCtx['pause']()
    },
    /**
     * Canvas绘制圆角
     * @param ctx
     * @param x
     * @param y
     * @param width
     * @param height
     * @param radius
     */
    drawRoundedRect(ctx, x, y, width, height, radius) {
      ctx.moveTo(x + radius, y)
      ctx.lineTo(x + width - radius, y)
      ctx.arc(x + width - radius, y + radius, radius, 1.5 * Math.PI, 2 * Math.PI)
      ctx.lineTo(x + width, y + height - radius)
      ctx.arc(x + width - radius, y + height - radius, radius, 0, 0.5 * Math.PI)
      ctx.lineTo(x + radius, y + height)
      ctx.arc(x + radius, y + height - radius, radius, 0.5 * Math.PI, Math.PI)
      ctx.lineTo(x, y + radius)
      ctx.arc(x + radius, y + radius, radius, Math.PI, 1.5 * Math.PI)
    }
  }
}
</script>

<style lang="scss" scoped>
.chat-item {
  display: flex;
  padding: 0 20rpx;
  box-sizing: border-box;
  width: 100%;
  margin-top: 30rpx;
  &.is-self {
    flex-direction: row-reverse;
    .chat-content {
      margin-left: 0;
      margin-right: 20rpx;
    }
  }
  .chat-face {
    width: 80rpx;
    height: 80rpx;
    border-radius: 20rpx;
    flex-shrink: 0;
  }
  .chat-content {
    margin-left: 20rpx;
    min-height: 80rpx;
    background-color: #ffffff;
    border-radius: 20rpx;
    max-width: 484rpx;
    padding: 20rpx;
    box-sizing: border-box;
    &.IMAGES,
    &.VIDEO {
      padding: 0;
      background-color: transparent;
    }

    /deep/ .emoji-img {
      display: inline-block;
      width: 30rpx;
      height: 30rpx;
      font-size: 0;
      margin: 0;
      vertical-align: bottom;
    }
  }
  .rich-text {
    word-break: break-all;
  }
  .goods-message {
    display: flex;
    width: 444rpx;
    .goods-image {
      width: 160rpx;
      height: 160rpx;
      flex-shrink: 0;
    }
    .goods-info {
      display: flex;
      flex-direction: column;
      justify-content: center;
      width: 265rpx;
      margin-left: 20rpx;
    }
    .goods-name {
      width: 100%;
      height: 54rpx;
      font-size: 28rpx;
      line-height: 28rpx;
      display: -webkit-box;
      overflow: hidden;
      text-overflow: ellipsis;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
    }
    .goods-price {
      font-size: 28rpx;
      margin-top: 56rpx;
      color: #252525;
    }
  }
  .order-message {
    display: flex;
    flex-direction: column;
    width: 444rpx;
    background-color: #ffffff;
    overflow: hidden;
    box-sizing: border-box;
    .order-info {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
      text {
        font-size: 24rpx;
        color: #656665;
      }
    }
    .order-goods {
      display: flex;
      padding: 14rpx;
      margin-top: 20rpx;
      background-color: #f4f4f4;
      box-sizing: border-box;
      border-radius: 8rpx;
      .goods-image {
        width: 140rpx;
        height: 140rpx;
      }
      .goods-info {
        display: flex;
        flex-direction: column;
        justify-content: center;
        width: 265rpx;
        height: 140rpx;
        margin-left: 20rpx;
      }
      .goods-name {
        width: 100%;
        height: 54rpx;
        font-size: 28rpx;
        line-height: 28rpx;
        display: -webkit-box;
        overflow: hidden;
        text-overflow: ellipsis;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
      }
    }
      .order-price-status {
        display: flex;
        justify-content: space-between;
        margin-top: 32rpx;
      }
      .order-price,
      .order-status {
        font-size: 28rpx;
        color: #252525;
      }
      .order-status {
        color: #9d9d9c;
      }
  }
  .image-message {
    overflow: hidden;
    border-radius: 20rpx;
    .image {
      display: block;
      max-width: 300rpx;
      max-height: 300rpx;
      min-width: 100rpx;
      min-height: 100rpx;
      border-radius: 20rpx;
    }
  }
  .video-message {
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    overflow: hidden;
    border-radius: 20rpx;
    /* #ifndef H5 */
    background: rgba(0,0,0,.8);
    /* #endif */
    .video {
      display: block;
      height: 300rpx;
      border-radius: 20rpx;
      overflow: hidden;
      background-color: rgba(0,0,0,.5);
    }
    /* #ifndef H5 */
    .video {
      display: none;
    }
    &::after {
      content: '';
      position: absolute;
      width: 100rpx;
      height: 100rpx;
      background-size: 100% 100%;
      background-repeat: no-repeat;
      background-image: url('');
    }
    /* #endif */
  }
}
</style>
